/**
 * 
 */
package ifpb.edu;

import java.awt.geom.Area;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.TreeSet;

/**
 * @author ricardo
 *
 */
public class Banco {

	
	public Banco(){
		
	}
	
	
	/**
	 * 
	 */
	
	
	//---------Métodos que implementam as funções do Banco-------
	
	//este métido irá cadastrar uma agência no banco
	public boolean cadastrarAgencia(Agencia a) {
		
		TreeSet arvoreAgencia;
		try {
			
			arvoreAgencia = lerNoBancoDeDados("agencia.ser"); //salvando o conteúdo do arquivo na arvore
			arvoreAgencia.add(a); //adicionando um novo objeto a arvore
			escreverNoBancoDeDados(arvoreAgencia, "agencia.ser");//salvando as alterações
		
		}catch (ClassNotFoundException | IOException e) {
			return false;
		}
		//fim da lógica para cadastrar uma agência
		
		
		//Testando a persistência imprimindo todas as agências cadastradas
		try {
			
			TreeSet outraArvore = lerNoBancoDeDados("agencia.ser");
			System.out.println(outraArvore.toString());
			
		} catch (ClassNotFoundException | IOException e) {
			System.out.println("persistência falhou");
		}
		
		return true;
	}//fim do método cadastrarAgencia
	
	//este método pesquisa uma agência
	public Agencia pesquisarAgencia(String prefixoAgencia){
		
		Agencia a = new Agencia(prefixoAgencia);
		try {
			
			TreeSet arvore = lerNoBancoDeDados("agencia.ser");
			return (Agencia)arvore.ceiling(a); //retorna a agência, caso ela exista, ou null caso contrário
		
		} catch (ClassNotFoundException | IOException e) {
			return null;
		}
		
	}//fim do método perquisarAgencia
	
	
	public boolean cadastrarCliente(Cliente c){
		boolean bo = true;
		try {
			
			TreeSet<Cliente> arvoreCliente = lerNoBancoDeDados("cliente.ser"); //obtém a árvore contendo a lista de cliente
			bo = arvoreCliente.add(c); //adiciona o cliente a arvore de clientes
			escreverNoBancoDeDados(arvoreCliente, "cliente.ser"); //grava as alterações no banco de dados
						
		
		} catch (ClassNotFoundException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
		return bo;
	}
	
		
	//este método irá cadastrar um cliente em uma agência
	public void cadastrarClienteAgencia(Agencia a, Cliente c) {
		
		try {
			TreeSet<Agencia> arvoreAgencia = lerNoBancoDeDados("agencia.ser");
			TreeSet<Cliente> arvoreCliente = lerNoBancoDeDados("cliente.ser");
			Cliente c1 = arvoreCliente.ceiling(c);
			arvoreAgencia.ceiling(a).cadastrarCliente(c1);
			escreverNoBancoDeDados(arvoreAgencia, "agencia.ser");
						
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}//fim do método cadastrarClienteAgencia
	
	
	
	
	//este método irá pesquisar um cliente da agência e retornar o objeto cliente
	public Cliente PesquisarClienteAgencia(String prefixo, String cpf){
		
		try {
			Agencia ag = new Agencia(prefixo);
			Cliente cliente = new Cliente(cpf);
			TreeSet<Agencia> arvoreAgencia = lerNoBancoDeDados("agencia.ser");
			if(arvoreAgencia.contains(ag)){
				if (arvoreAgencia.ceiling(ag).getCliente().contains(cliente))
					return (Cliente)arvoreAgencia.ceiling(ag).getCliente().ceiling(cliente);
			}
			else return null;
			
		} catch (ClassNotFoundException | IOException e) {
			
		}
		return null;
	}
	
	//este método irá excluir um cliente de uma agência
	public boolean excluirClienteAgencia(Agencia ag, String cpf) {
		
		boolean retorno = false;
		TreeSet<Agencia> arvAg = new TreeSet<Agencia>();
		try {
			arvAg = lerNoBancoDeDados("agencia.ser");
		} catch (ClassNotFoundException | IOException e1) {
			return false;
		}
					
		if (arvAg.contains(ag)){
							
			Cliente c2 = new Cliente(cpf);
			if(arvAg.ceiling(ag).getCliente().contains(c2)){
				arvAg.ceiling(ag).getCliente().remove(c2);
				retorno = true;
				System.out.println("Cliente excluído");
				try {
					escreverNoBancoDeDados(arvAg, "agencia.ser");
				} catch (IOException e) {
					return false;
				}
			}
		}	
		return retorno;
	}//fim do método excluirClienteAgencia
	
	public boolean abrirConta(String prefixo, String cpf, int tipoConta) {
		boolean retorno = false;
		ContaCorrente ccteste = new ContaCorrente();
		Agencia ag = new Agencia(prefixo);
		TreeSet<Agencia> arvAg = new TreeSet<Agencia>();
		try {
			arvAg = lerNoBancoDeDados("agencia.ser");
		} catch (ClassNotFoundException | IOException e) {
			return false;
		}
		if (arvAg.contains(ag)){
			Cliente cliente = new Cliente(cpf);
			if (arvAg.ceiling(ag).getCliente().contains(cliente)){
				switch (tipoConta) {
				case 1://conta corrente
						int numeroConta1 = arvAg.ceiling(ag).getNumeroConta() + 1;
						arvAg.ceiling(ag).setNumeroConta(numeroConta1);
						ContaCorrente cc = new ContaCorrente(numeroConta1);
						arvAg.ceiling(ag).getConta().add(cc);
						arvAg.ceiling(ag).getMapa().put(cc, cliente);
						ContaCorrente cc2 = (ContaCorrente)arvAg.ceiling(ag).getConta().ceiling(cc);
						System.out.println(cc2.getNumeroConta());
						System.out.println("");
						retorno = true;
						ccteste = cc;
				break;
				case 2://conta poupança
						int numeroConta = arvAg.ceiling(ag).getNumeroConta() + 1;
						arvAg.ceiling(ag).setNumeroConta(numeroConta);
						ContaPoupanca cp = new ContaPoupanca(numeroConta);
						arvAg.ceiling(ag).getConta().add(cp);
						arvAg.ceiling(ag).getMapa().put(cp, cliente);
						ContaPoupanca cp1 = (ContaPoupanca)arvAg.ceiling(ag).getConta().ceiling(cp);
						System.out.println(cp1.getNumeroConta());
						System.out.println("");
						retorno = true;
						
				break;
				
				}//fim do swich/case
					try {
						escreverNoBancoDeDados(arvAg, "agencia.ser");
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					try {
						TreeSet<Agencia> tsa= lerNoBancoDeDados("agencia.ser");
						ContaCorrente contac= (ContaCorrente)tsa.ceiling(ag).getConta().ceiling(ccteste);
						System.out.println("O número da conta é: ");
						System.out.println(contac.getNumeroConta());
					} catch (ClassNotFoundException | IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				
			}//fim do if
		}//fim do if
		
		return retorno;
		
	}
	
	
	// ------------------Métodos para ler e escrever no banco de dados----------------------------------------------
	
		public TreeSet lerNoBancoDeDados(String nomeArquivo) throws IOException, ClassNotFoundException{
			TreeSet arvore;// = new TreeSet(); // criação de uma coleção que guardará objetos do projeto(agência, ou cliente, etc)
			FileInputStream fis = new FileInputStream(nomeArquivo); //leitura do arquivo contendo os objetos já adicionados
			ObjectInputStream objRead = new ObjectInputStream(fis);
						
			arvore = (TreeSet)objRead.readObject(); // salvando na estrutura de arvore o conteúdo que existe dentro do arquivo
			objRead.close();
			return arvore;
		}
		
		public void escreverNoBancoDeDados(TreeSet ts, String nomeArquivo) throws IOException{
			FileOutputStream fos = new FileOutputStream(nomeArquivo);
			ObjectOutputStream objWrite = new ObjectOutputStream(fos);
					
			objWrite.writeObject(ts); //gravando as alterações no arquivo
			objWrite.close();
			
		}


		



	

	
}
